home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / hardware / cpu115 / cpuspeed.asm < prev    next >
Assembly Source File  |  1995-02-27  |  6KB  |  330 lines

  1. ; -----------------------------------------------------------------------------
  2. ; CPUSPEED.ASM  CPU speed measurement routine            Version 1.15 
  3. ;
  4. ; Too-Much-In-One-So-Don't-Get-Lost(tm) CPU/FPU feature detection library
  5. ;
  6. ; Copyright(c) 1993-95 by B-coolWare.  Written by Bobby Z.
  7. ; -----------------------------------------------------------------------------
  8.  
  9.     INCLUDE    HEADER.ASH
  10.  
  11.     .DATA
  12.  
  13.     EXTRN    CPUFix: DWORD        ; CPU Type speed fix constant
  14.     EXTRN    Shift : WORD        ; current loop length
  15.  
  16.     .CODE
  17.  
  18. ifndef    __use_386__
  19.  ifdef  __use_286__
  20.     .286
  21.  endif
  22. else
  23.  __use_286__    equ    1
  24.     .386
  25. endif
  26.  
  27.     PUBLIC    Speed   
  28.  
  29. _bpes    equ    <byte ptr es:>
  30. _wp    equ    <word ptr>
  31.  
  32. clr    macro    reg
  33.     sub    reg,reg
  34.     endm
  35.  
  36. IsUnderWin    proc near
  37.     mov    ax,1600h
  38.     int    2Fh
  39.     or    al,al
  40.     jz    @@nowin
  41.     cmp    al,80h
  42.     jz    @@nowin
  43.     stc
  44.     ret
  45. @@nowin:
  46.     clc
  47.     ret
  48.     endp
  49.  
  50.  
  51. WinStartCritical    proc near
  52.     push    ax
  53.     call    IsUnderWin
  54.     jnc    @@Q
  55.     mov    ax,1681h
  56.     int    2Fh
  57. @@Q:
  58.     pop    ax
  59.     ret
  60.     endp
  61.  
  62. WinEndCritical        proc near
  63.     push    ax
  64.     call    IsUnderWin
  65.     jnc    @@Q
  66.     mov    ax,1682h
  67.     int    2Fh
  68. @@Q:
  69.     pop    ax
  70.     ret
  71.     endp
  72.  
  73. isUnderDV    proc near
  74.     mov    ax,2B01h
  75.     push    cx dx
  76.     mov    cx,4445h
  77.     mov    dx,5351h
  78.     int    21h
  79.     pop    dx cx
  80.     cmp    al,0FFh
  81.     jz    @@noDV
  82.     stc
  83.     ret
  84. @@noDV:
  85.     clc
  86.     ret
  87.     endp
  88.  
  89. DVStartCritical    proc near
  90.     push    ax
  91.     call    isUnderDV
  92.     jnc    @@Q
  93.     mov    ax,101Bh
  94.     int    15h
  95. @@Q:
  96.     pop    ax
  97.     ret
  98.     endp
  99.  
  100. DVEndCritical    proc near
  101.     push    ax
  102.     call    isUnderDV
  103.     jnc    @@Q
  104.     mov    ax,101Ch
  105.     int    15h
  106. @@Q:
  107.     pop    ax
  108.     ret
  109.     endp
  110.  
  111.  
  112. ; -----------------------------------------------------------------------
  113. ; Speed modifies CPUFix and Shift and returns value which should b used
  114. ; as follows:
  115. ;
  116. ; CPUSpeed_In_MHz := (((CPUFix*Shift)/Speed)+5)/10;
  117. ;
  118. ; This formulae is taken from Norton SysInfo unchanged. I've no idea why
  119. ; computations done this way, but it works ok.
  120. ; I dinna insert floating point here, but to use with assembler you'll have to
  121. ; do so.
  122. ; Shift should be converted to DWORD prior to multiplication.
  123. ; Resulting value may be rounded to nearest integer, or may be left unchanged
  124. ; if you want exact CLK frequency value.
  125.  
  126. ; function Speed( CPUid : Byte ) : Word;
  127. ; unsigned int Speed( unsigned short CPUid );
  128.  
  129. ; CPUid is value from 0 to 13h identifying processor we're running on
  130. ; 8088   = 00h
  131. ; 8086   = 01h
  132. ; V20    = 02h
  133. ; V30    = 03h
  134. ; 188    = 04h
  135. ; 186    = 05h
  136. ; 286    = 06h
  137. ; 386sx  = 07h
  138. ; 386dx  = 08h
  139. ; 386sl  = 09h
  140. ; 486sx  = 0Ah
  141. ; 486dx  = 0Bh
  142. ; 486slc = 0Ch
  143. ; Cx486  = 0Dh
  144. ; P5     = 0Eh
  145. ; CxM1     = 0Fh
  146. ; Am386sx= 10h
  147. ; Am386dx= 11h
  148. ; UMC U5s= 12h
  149. ; UMC U5d= 13h    -??? I don't know if this CPU really exists...
  150.  
  151. ; It is lower byte of the result of CPU_Type routine defined in CPU_TYPE.ASH
  152. ; or CPU_HL.ASM.
  153.  
  154. MaxCPUid    equ    14h    ; change this if you added new CPU types
  155.  
  156. Speed    PROC
  157. ARG    CPUid:BYTE
  158. ifdef    __DPMI__
  159.     mov    ax,dpmiCreateCodeAlias
  160.     mov    bx,cs
  161.     int    31h
  162.     mov    es,ax
  163. else
  164.     push    cs
  165.     pop    es
  166. endif
  167.     cmp    CPUid,MaxCPUid    ; checking if we know this CPU
  168.     jbe    @@okcpu
  169.     mov    CPUid,MaxCPUid    ; fixing CPU id - let's assume it's P5 or
  170.                 ; better :)
  171. @@okcpu:
  172.     mov    cx,2
  173.     mov    _bpes[Indic],0
  174.     call    WinStartCritical
  175.     call    DVStartCritical
  176. @@1:
  177.     mov    Shift,cx
  178.     call    Speed_Test
  179.     cmp    ax,1000h
  180.     jnb    @@2
  181.     mov    cx,Shift
  182.     shl    cx,1
  183.     shl    cx,1
  184.     shl    cx,1
  185.     jmp    @@1
  186. @@2:
  187.     push    ax
  188.     mov    cx,Shift
  189.     mov    _bpes[Indic],1
  190.     call    Speed_Test
  191.     call    WinEndCritical
  192.     call    DVEndCritical
  193.     pop    dx
  194.     sub    dx,ax
  195.     xchg    ax,dx
  196. ifdef    __use_386__
  197.     movzx    bx,CPUid
  198. else
  199.     mov    bl,CPUid
  200.     clr    bh
  201. endif
  202. ifdef    __use_286__
  203.     shl    bx,2
  204. else
  205.     shl    bx,1
  206.     shl    bx,1
  207. endif
  208. ifdef    __use_386__
  209.     mov    edx,es:CPUFixes[bx]
  210.     mov    CPUFix,edx
  211. else
  212.     mov    dx,_wp es:CPUFixes[bx]
  213.     mov    _wp CPUFix,dx
  214.     mov    dx,_wp es:CPUFixes[2][bx]
  215.     mov    _wp CPUFix[2],dx
  216. endif
  217. ifdef    __DPMI__
  218.     push    ax bx
  219.     mov    ax,dpmiFreeLDTDesc
  220.     mov    bx,es
  221.     int    31h
  222.     pop    bx ax
  223. endif
  224.     ret
  225.     ENDP
  226.  
  227. Speed_Test    PROC    NEAR
  228. ; returns number of tick-tacks spent performing known instruction?
  229. ; or difference between time taken by plain group of similar instructions and
  230. ; time taken by loop of that instructions? I dinna find out what exactly it
  231. ; does, but it works - what else do i (and u) need? 
  232.  
  233.     PUSH    SI DI
  234.     CLR    DX,DX
  235.     MOV    SI,0AAAAH
  236.     MOV    BX,05555H
  237.     IN    AL,61h
  238.     JMP    $+2
  239.     AND    AL,0FCH
  240.     OUT    61h,AL
  241.     JMP    $+2
  242.     MOV    AL,0B4h
  243.     OUT    43h,AL
  244.     JMP    $+2
  245.     CLR    AL
  246.     OUT    42h,AL
  247.     JMP    $+2
  248.     OUT    42h,AL
  249.     JMP    $+2
  250.     IN    AL,61h
  251.     MOV    DI,AX
  252.     OR    AL,01
  253.     CMP    _BPES[INDIC],0
  254.     JZ    @@1
  255.     JMP    @@2
  256. @@1:
  257.     CLI
  258.     OUT    61h,AL
  259. @@3:
  260. Sprite    equ    <8Bh, 0C6h, 0F7h, 0F3h>
  261. ;    MOV    AX,SI
  262. ;    DIV    BX
  263.     db    101    dup(Sprite)
  264.     DEC    CX
  265.     JZ    @@4
  266.     JMP    @@3
  267. @@2:
  268.     CLI
  269.     OUT    61h,AL
  270.     NOP            ; well, maybe this is the right place for
  271.                 ; NOP, so i left it here. Try to kill it and
  272.                 ; see what will happen...
  273. @@5:
  274.     db    Sprite
  275.     DEC    CX
  276.     JZ    @@4
  277.     JMP    @@5
  278.  
  279. @@4:
  280.     MOV    AX,DI
  281.     OUT    61h,AL
  282.     JMP    $+2
  283.     STI
  284.     IN    AL,42h
  285.     JMP    $+2
  286.     XCHG    AH,AL
  287.     IN    AL,42h
  288.     JMP    $+2
  289.     XCHG    AH,AL
  290.     NEG    AX
  291.     PUSH    AX
  292.     IN    AL,61h
  293.     JMP    $+2
  294.     AND    AL,0FDh
  295.     OUT    61h,AL
  296.     POP    AX DI SI
  297.     RET
  298.     ENDP
  299. Indic    db    ?
  300.  
  301. CPUFixes:
  302.  
  303. ; For on different processors the same instruction takes different number of 
  304. ; CPU clocks, we should adjust absolute timer value using our knowledge of
  305. ; known CPU's timings.
  306.  
  307.     dd    2AD26h        ; 8088
  308.     dd    2AD26h        ; 8086
  309.     dd    0E90Bh        ; V20
  310.     dd    0DFB9h        ; V30
  311.     dd    0BA6Fh        ; 188
  312.     dd    0BA6Fh        ; 186
  313.     dd    06FDCh        ; 286
  314.     dd    07486h        ; 386sx
  315.     dd    07486h        ; 386dx
  316.     dd    07486h        ; 386sl
  317.     dd    07486h        ; 486sx
  318.     dd    07486h        ; 486dx
  319.     dd    0668Ah        ; Cx486slc
  320.     dd    0668Ah        ; Cx486sx/dx/dlc
  321.     dd    0792Fh        ; Pentium
  322.     dd    0668Ah        ; CxM1
  323.     dd    0792Fh        ; P24D
  324.     dd    07415h        ; Am386sx
  325.     dd    07415h        ; Am386dx
  326.     dd    0792Fh        ; UMC U5-S
  327.     dd    0792Fh        ; UMC U5-D
  328.  
  329.     END
  330.